/**
 * @file lcd_drive_internal.h
 * @author cangyu (sky.kirto@qq.com)
 * @brief
 * @version 0.1
 * @date 2024-09-02
 *
 * @copyright Copyright (c) 2024, CorAL. All rights reserved.
 *
 */

#ifndef __LCD_DRIVE_INTERNAL_H__
#define __LCD_DRIVE_INTERNAL_H__

/* ==================== [Includes] ========================================== */

#include "lcd_drive.h"

#ifdef __cplusplus
extern "C" {
#endif

/* ==================== [Defines] =========================================== */

#define LCD_SWRESET 0x01  // Software Reset
#define LCD_RDDID   0x04  // Read Display ID
#define LCD_INVOFF  0x20  // Display Inversion Off
#define LCD_INVON   0x21  // Display Inversion On
#define LCD_CASET   0x2A  // Column Address Set
#define LCD_PASET   0x2B  // Row Address Set
#define LCD_RAMWR   0x2C  // Memory Writ
#define LCD_RAMRD   0x2E  // Memory Read
#define LCD_MADCTL  0x36  // Memory Data Access Control

/* MADCTL Defines */
#define MADCTL_MY  0x80
#define MADCTL_MX  0x40
#define MADCTL_MV  0x20
#define MADCTL_ML  0x10
#define MADCTL_RGB 0x08
#define MADCTL_MH  0x04

#define LCD_WRITE_CMD(self, cmd, len)  lcd_get_in(self)->write_cmd(cmd, len)
#define LCD_WRITE_DATA(self, data, len)  lcd_get_in(self)->write_data(data, len)
#define LCD_RESET(self)  lcd_get_in(self)->reset()
#define LCD_BACKLIGHT(self, is_on)  lcd_get_in(self)->backlight(is_on)

/* ==================== [Typedefs] ========================================== */

typedef xf_err_t (*lcd_init_t)(lcd_t self);
typedef xf_err_t (*lcd_draw_bitmap_t)(lcd_t self, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *bitmap);

typedef struct _lcd_drive_out_t {
    uint16_t res_hor;    /*!< 最大宽度 */
    uint16_t res_ver;    /*!< 最大高度 */
    lcd_init_t init;
    lcd_draw_bitmap_t draw_bitmap;
} lcd_drive_out_t;

/* ==================== [Global Prototypes] ================================= */

void lcd_controller_driver_reg(lcd_scr_controller_t controller, const lcd_drive_out_t *out);
void lcd_drive_offset(lcd_t self, uint16_t *x0, uint16_t *y0, uint16_t *x1, uint16_t *y1);
lcd_drive_in_t *lcd_get_in(lcd_t self);

/* ==================== [Macros] ============================================ */

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif // __LCD_DRIVE_INTERNAL_H__
